package com.youkeyi.ddy.cloud.application.system.position.controller;

import com.youkeyi.ddy.cloud.common.api.application.system.auth.dto.SystemAuthListItemCloudDto;
import com.youkeyi.ddy.cloud.common.api.application.system.organization.dto.SystemOrganizationListItemCloudDto;
import com.youkeyi.ddy.cloud.common.api.application.system.position.SystemPositionCloudService;
import com.youkeyi.ddy.cloud.common.api.application.system.position.dto.SystemPositionDetailCloudDto;
import com.youkeyi.ddy.cloud.common.api.application.system.position.dto.SystemPositionListCloudDto;
import com.youkeyi.ddy.cloud.common.api.application.system.position.dto.SystemPositionListItemCloudDto;
import com.youkeyi.ddy.cloud.common.api.application.system.position.param.SystemPositionCreateCloudParam;
import com.youkeyi.ddy.cloud.common.api.application.system.position.param.SystemPositionDeleteCloudParam;
import com.youkeyi.ddy.cloud.common.api.application.system.position.param.SystemPositionListCloudParam;
import com.youkeyi.ddy.cloud.common.api.application.system.position.param.SystemPositionUpdateCloudParam;
import com.youkeyi.ddy.cloud.common.api.application.system.user.dto.SystemUserListItemCloudDto;
import com.youkeyi.ddy.cloud.common.api.basic.pub.auth.PublicAuthCloudService;
import com.youkeyi.ddy.cloud.common.api.basic.pub.auth.dto.PublicAuthListCloudDto;
import com.youkeyi.ddy.cloud.common.api.basic.pub.auth.param.PublicAuthQueryCloudParam;
import com.youkeyi.ddy.cloud.common.api.basic.pub.corp.PublicCorpCloudService;
import com.youkeyi.ddy.cloud.common.api.basic.pub.corp.dto.PublicCorpListCloudDto;
import com.youkeyi.ddy.cloud.common.api.basic.pub.corp.dto.PublicCorpListItemCloudDto;
import com.youkeyi.ddy.cloud.common.api.basic.pub.corp.param.PublicCorpQueryCloudParam;
import com.youkeyi.ddy.cloud.common.api.basic.pub.mapping.PublicMappingCloudService;
import com.youkeyi.ddy.cloud.common.api.basic.pub.mapping.dto.PublicMappingListCloudDto;
import com.youkeyi.ddy.cloud.common.api.basic.pub.mapping.dto.PublicMappingListItemCloudDto;
import com.youkeyi.ddy.cloud.common.api.basic.pub.mapping.param.PublicMappingQueryCloudParam;
import com.youkeyi.ddy.cloud.common.api.basic.pub.position.PublicPositionCloudService;
import com.youkeyi.ddy.cloud.common.api.basic.pub.position.dto.PublicPositionListCloudDto;
import com.youkeyi.ddy.cloud.common.api.basic.pub.position.dto.PublicPositionListItemCloudDto;
import com.youkeyi.ddy.cloud.common.api.basic.pub.position.param.PublicPositionCreateCloudParam;
import com.youkeyi.ddy.cloud.common.api.basic.pub.position.param.PublicPositionDeleteCloudParam;
import com.youkeyi.ddy.cloud.common.api.basic.pub.position.param.PublicPositionQueryCloudParam;
import com.youkeyi.ddy.cloud.common.api.basic.pub.position.param.PublicPositionUpdateCloudParam;
import com.youkeyi.ddy.cloud.common.api.basic.pub.user.PublicUserCloudService;
import com.youkeyi.ddy.cloud.common.api.basic.pub.user.dto.PublicUserListCloudDto;
import com.youkeyi.ddy.cloud.common.api.basic.pub.user.param.PublicUserQueryCloudParam;
import com.youkeyi.ddy.cloud.common.constant.YoukeyiDdyCloudBasicPublicConstant;
import com.youkeyi.ddy.cloud.common.context.YoukeyiSystemContext;
import com.youkeyi.ddy.cloud.common.enums.ResponseCodeEnum;
import com.youkeyi.ddy.cloud.common.response.ResponseContent;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * SystemPositionController
 *
 * @Author liuxiawang
 * @Date 2024/2/29 10:32 AM
 * @Location shenzhen.china
 */
@Service
public class SystemPositionController implements SystemPositionCloudService {

    @Autowired
    private PublicPositionCloudService publicPositionCloudService;
    @Autowired
    private PublicAuthCloudService publicAuthCloudService;
    @Autowired
    private PublicMappingCloudService publicMappingCloudService;
    @Autowired
    private PublicUserCloudService publicUserCloudService;
    @Autowired
    private PublicCorpCloudService publicCorpCloudService;

    @Override
    public SystemPositionListCloudDto list(SystemPositionListCloudParam param) {
        SystemPositionListCloudDto dto = new SystemPositionListCloudDto();
        String corpKey = YoukeyiSystemContext.getCorpPrimaryKey();
        Integer isRoot = YoukeyiSystemContext.getIsRoot();
        if (StringUtils.isBlank(corpKey)) {
            dto.setErrorMessage(ResponseCodeEnum.TOKEN_INVALID.getMessage());
            return dto;
        }
        if (null == param) {
            dto.setErrorMessage(ResponseCodeEnum.PARAMETER_ILLEGAL.getMessage());
            return dto;
        }

        PublicPositionQueryCloudParam positionQueryCloudParam = new PublicPositionQueryCloudParam();
        positionQueryCloudParam.setPositionPrimaryKeys(param.getPositionPrimaryKeys());
        if (2 != isRoot) {
            positionQueryCloudParam.setCorpKeys(Collections.singletonList(corpKey));
        }
        positionQueryCloudParam.setNames(param.getNames());
        positionQueryCloudParam.setNameFuzzy(param.getNameFuzzy());
        positionQueryCloudParam.setCodes(param.getCodes());
        positionQueryCloudParam.setOrganizationKeys(Collections.singletonList(param.getOrganizationKey()));
        positionQueryCloudParam.setPageSize(param.getPageSize());
        positionQueryCloudParam.setCurrentPage(param.getCurrentPage());
        positionQueryCloudParam.setNeedOrganization(Boolean.TRUE);
        PublicPositionListCloudDto positionDtos = publicPositionCloudService.query(positionQueryCloudParam);
        if (null != positionDtos && CollectionUtils.isNotEmpty(positionDtos.getRows())) {
            PublicCorpQueryCloudParam corpQueryCloudParam = new PublicCorpQueryCloudParam();
            corpQueryCloudParam.setCorpPrimaryKeys(positionDtos.getRows().stream().map(PublicPositionListItemCloudDto::getCorpKey).collect(Collectors.toList()));
            PublicCorpListCloudDto corpDtos = publicCorpCloudService.query(corpQueryCloudParam);
            Map<String, String> corpMap = new HashMap<>();
            if (CollectionUtils.isNotEmpty(corpDtos.getRows())) {
                corpMap.putAll(corpDtos.getRows().stream().collect(Collectors.toMap(PublicCorpListItemCloudDto::getCorpPrimaryKey, PublicCorpListItemCloudDto::getName, (k1, k2) -> k1)));
            }

            List<SystemPositionListItemCloudDto> items = new ArrayList<>();
            positionDtos.getRows().forEach(position -> {
                SystemPositionListItemCloudDto item = new SystemPositionListItemCloudDto();
                item.setPositionPrimaryKey(position.getPositionPrimaryKey());
                item.setName(position.getName());
                item.setCode(position.getCode());
                item.setDesc(position.getDesc());
                item.setIsDeleted(position.getIsDeleted());
                item.setIsDeletedName(position.getIsDeletedName());
                item.setCreateUserKey(position.getCreateUserKey());
                item.setCreateUserName(position.getCreateUserName());
                if (null != position.getOrganization()) {
                    item.setOrganizationPrimaryKey(position.getOrganization().getOrganizationPrimaryKey());
                    item.setOrganizationName(position.getOrganization().getName());
                }
                item.setCorpPrimaryKey(position.getCorpKey());
                item.setCorpName(corpMap.get(position.getCorpKey()));
                items.add(item);
            });
            dto.setRows(items);
            dto.setTotal(positionDtos.getTotal());
        }
        dto.setSuccessMessage(ResponseCodeEnum.SUCCESS.getMessage());
        return dto;
    }

    @Override
    public SystemPositionListCloudDto simpleList(SystemPositionListCloudParam param) {
        SystemPositionListCloudDto dto = new SystemPositionListCloudDto();
        String corpKey = YoukeyiSystemContext.getCorpPrimaryKey();
        if (StringUtils.isBlank(corpKey)) {
            dto.setErrorMessage(ResponseCodeEnum.TOKEN_INVALID.getMessage());
            return dto;
        }
        if (null == param) {
            dto.setErrorMessage(ResponseCodeEnum.PARAMETER_ILLEGAL.getMessage());
            return dto;
        }

        PublicPositionQueryCloudParam positionQueryCloudParam = new PublicPositionQueryCloudParam();
        positionQueryCloudParam.setOrganizationKeys(Collections.singletonList(param.getOrganizationKey()));
        positionQueryCloudParam.setNeedOrganization(Boolean.TRUE);
        PublicPositionListCloudDto positionDtos = publicPositionCloudService.query(positionQueryCloudParam);
        if (null != positionDtos && CollectionUtils.isNotEmpty(positionDtos.getRows())) {
            PublicCorpQueryCloudParam corpQueryCloudParam = new PublicCorpQueryCloudParam();
            corpQueryCloudParam.setCorpPrimaryKeys(positionDtos.getRows().stream().map(PublicPositionListItemCloudDto::getCorpKey).collect(Collectors.toList()));
            PublicCorpListCloudDto corpDtos = publicCorpCloudService.query(corpQueryCloudParam);
            Map<String, String> corpMap = new HashMap<>();
            if (CollectionUtils.isNotEmpty(corpDtos.getRows())) {
                corpMap.putAll(corpDtos.getRows().stream().collect(Collectors.toMap(PublicCorpListItemCloudDto::getCorpPrimaryKey, PublicCorpListItemCloudDto::getName, (k1, k2) -> k1)));
            }

            List<SystemPositionListItemCloudDto> items = new ArrayList<>();
            positionDtos.getRows().forEach(position -> {
                SystemPositionListItemCloudDto item = new SystemPositionListItemCloudDto();
                item.setPositionPrimaryKey(position.getPositionPrimaryKey());
                item.setName(position.getName());
                item.setCode(position.getCode());
                item.setDesc(position.getDesc());
                item.setIsDeleted(position.getIsDeleted());
                item.setIsDeletedName(position.getIsDeletedName());
                item.setCreateUserKey(position.getCreateUserKey());
                item.setCreateUserName(position.getCreateUserName());
                if (null != position.getOrganization()) {
                    item.setOrganizationPrimaryKey(position.getOrganization().getOrganizationPrimaryKey());
                    item.setOrganizationName(position.getOrganization().getName());
                }
                item.setCorpPrimaryKey(position.getCorpKey());
                item.setCorpName(corpMap.get(position.getCorpKey()));
                items.add(item);
            });
            dto.setRows(items);
            dto.setTotal(positionDtos.getTotal());
        }
        dto.setSuccessMessage(ResponseCodeEnum.SUCCESS.getMessage());
        return dto;
    }

    @Override
    public SystemPositionDetailCloudDto detail(String positionPrimaryKey) {
        SystemPositionDetailCloudDto dto = new SystemPositionDetailCloudDto();
        String corpKey = YoukeyiSystemContext.getCorpPrimaryKey();
        if (StringUtils.isBlank(corpKey)) {
            dto.setErrorMessage(ResponseCodeEnum.TOKEN_INVALID.getMessage());
            return dto;
        }
        if (StringUtils.isBlank(positionPrimaryKey)) {
            dto.setErrorMessage(ResponseCodeEnum.PARAMETER_ILLEGAL.getMessage());
            return dto;
        }

        PublicPositionQueryCloudParam positionQueryCloudParam = new PublicPositionQueryCloudParam();
        // positionQueryCloudParam.setCorpKeys(Collections.singletonList(corpKey));
        positionQueryCloudParam.setPositionPrimaryKeys(Collections.singletonList(positionPrimaryKey));
        positionQueryCloudParam.setNeedOrganization(Boolean.TRUE);
        PublicPositionListCloudDto positions = publicPositionCloudService.query(positionQueryCloudParam);
        if (null != positions && CollectionUtils.isNotEmpty(positions.getRows())) {
            PublicPositionListItemCloudDto position = positions.getRows().get(0);
            dto.setPositionPrimaryKey(position.getPositionPrimaryKey());
            dto.setName(position.getName());
            dto.setPositionCode(position.getCode());
            dto.setDesc(position.getDesc());
            dto.setIsDeleted(position.getIsDeleted());
            dto.setIsDeletedName(position.getIsDeletedName());
            dto.setCreateUserKey(position.getCreateUserKey());
            dto.setCreateUserName(position.getCreateUserName());
            dto.setCreateTime(position.getCreateTime());
            dto.setUpdateUserKey(position.getUpdateUserKey());
            dto.setUpdateUserName(position.getUpdateUserName());
            dto.setUpdateTime(position.getUpdateTime());

            // 组织信息
            if (null != position.getOrganization()) {
                SystemOrganizationListItemCloudDto organizationItem = new SystemOrganizationListItemCloudDto();
                organizationItem.setOrganizationPrimaryKey(position.getOrganization().getOrganizationPrimaryKey());
                organizationItem.setName(position.getOrganization().getName());
                organizationItem.setCode(position.getOrganization().getCode());
                organizationItem.setIsShare(position.getIsShare());
                organizationItem.setLevel(position.getOrganization().getLevel());
                organizationItem.setType(position.getOrganization().getType());
                dto.setOrganization(organizationItem);
            }
            // 权限信息
            if (CollectionUtils.isNotEmpty(position.getAuthKeys())) {
                PublicAuthQueryCloudParam authQueryCloudParam = new PublicAuthQueryCloudParam();
                authQueryCloudParam.setAuthPrimaryKeys(position.getAuthKeys());
                PublicAuthListCloudDto authDtos = publicAuthCloudService.query(authQueryCloudParam);
                if (null != authDtos && CollectionUtils.isNotEmpty(authDtos.getRows())) {
                    authDtos.getRows().forEach(auth -> {
                        SystemAuthListItemCloudDto authItem = new SystemAuthListItemCloudDto();
                        authItem.setAuthPrimaryKey(auth.getAuthPrimaryKey());
                        authItem.setName(auth.getName());
                        authItem.setCode(auth.getCode());
                        authItem.setAuthType(auth.getAuthType());
                        authItem.setUrl(auth.getUrl());
                        dto.getAuths().add(authItem);
                    });
                }
            }
            // 用户信息
            PublicMappingQueryCloudParam publicMappingQueryCloudParam = new PublicMappingQueryCloudParam();
            publicMappingQueryCloudParam.setMappingType(YoukeyiDdyCloudBasicPublicConstant.PUBLIC_MAPPING_TYPE_USER_POSITION.value());
            publicMappingQueryCloudParam.setKeyType(YoukeyiDdyCloudBasicPublicConstant.PUBLIC_MAPPING_KEY_TYPE_TARGET.value());
            publicMappingQueryCloudParam.setKeys(Collections.singletonList(position.getPositionPrimaryKey()));
            PublicMappingListCloudDto publicMappingDtos = publicMappingCloudService.query(publicMappingQueryCloudParam);
            if (null != publicMappingDtos && CollectionUtils.isNotEmpty(publicMappingDtos.getRows())) {
               List<String> userKeys = publicMappingDtos.getRows().stream().map(PublicMappingListItemCloudDto::getSourceKey).collect(Collectors.toList());

                PublicUserQueryCloudParam userQueryCloudParam = new PublicUserQueryCloudParam();
                userQueryCloudParam.setUserPrimaryKeys(userKeys);
                userQueryCloudParam.setCorpKeys(Collections.singletonList(corpKey));
                PublicUserListCloudDto userDtos = publicUserCloudService.query(userQueryCloudParam);
                if (null != userDtos && CollectionUtils.isNotEmpty(userDtos.getRows())) {
                    userDtos.getRows().forEach(user -> {
                        SystemUserListItemCloudDto userItem = new SystemUserListItemCloudDto();
                        userItem.setUserPrimaryKey(user.getUserPrimaryKey());
                        userItem.setName(user.getName());
                        userItem.setNickName(user.getNickName());
                        userItem.setPhone(user.getPhone());
                        userItem.setEmail(user.getEmail());
                        userItem.setAvatarUrl(user.getAvatarUrl());
                        dto.getUsers().add(userItem);
                    });
                }
            }
        }
        dto.setSuccessMessage(ResponseCodeEnum.SUCCESS.getMessage());
        return dto;
    }

    @Override
    public ResponseContent create(SystemPositionCreateCloudParam param) {
        ResponseContent rc = new ResponseContent();
        String corpKey = YoukeyiSystemContext.getCorpPrimaryKey();
        if (StringUtils.isBlank(corpKey)) {
            rc.setErrorMessage(ResponseCodeEnum.TOKEN_INVALID.getMessage());
            return rc;
        }
        if (null == param
                || StringUtils.isBlank(param.getName())
        ) {
            rc.setErrorMessage(ResponseCodeEnum.PARAMETER_ILLEGAL.getMessage());
            return rc;
        }

        PublicPositionCreateCloudParam positionCreateCloudParam = new PublicPositionCreateCloudParam();
        positionCreateCloudParam.setCorpKey(StringUtils.defaultIfEmpty(param.getCorpKey(), corpKey));
        positionCreateCloudParam.setName(param.getName());
        positionCreateCloudParam.setCode(param.getCode());
        positionCreateCloudParam.setOrganizationKey(param.getOrganizationKey());
        positionCreateCloudParam.setAuthKeys(param.getAuthKeys());
        positionCreateCloudParam.setDesc(param.getDesc());
        positionCreateCloudParam.setCreateUserKey(YoukeyiSystemContext.getUserPrimaryKey());
        positionCreateCloudParam.setCreateUserName(YoukeyiSystemContext.getUserName());
        return publicPositionCloudService.create(positionCreateCloudParam);
    }

    @Override
    public ResponseContent update(SystemPositionUpdateCloudParam param) {
        ResponseContent rc = new ResponseContent();
        String corpKey = YoukeyiSystemContext.getCorpPrimaryKey();
        if (StringUtils.isBlank(corpKey)) {
            rc.setErrorMessage(ResponseCodeEnum.TOKEN_INVALID.getMessage());
            return rc;
        }
        if (null == param
                || StringUtils.isBlank(param.getPositionPrimaryKey())
                || StringUtils.isBlank(param.getName())
                || StringUtils.isBlank(param.getCode())
        ) {
            rc.setErrorMessage(ResponseCodeEnum.PARAMETER_ILLEGAL.getMessage());
            return rc;
        }

        PublicPositionUpdateCloudParam positionUpdateCloudParam = new PublicPositionUpdateCloudParam();
        positionUpdateCloudParam.setPositionPrimaryKey(param.getPositionPrimaryKey());
        positionUpdateCloudParam.setName(param.getName());
        positionUpdateCloudParam.setCode(param.getCode());
        positionUpdateCloudParam.setOrganizationKey(param.getOrganizationKey());
        positionUpdateCloudParam.setAuthKeys(param.getAuthKeys());
        positionUpdateCloudParam.setDesc(param.getDesc());
        positionUpdateCloudParam.setUpdateUserKey(YoukeyiSystemContext.getUserPrimaryKey());
        positionUpdateCloudParam.setUpdateUserName(YoukeyiSystemContext.getUserName());
        return publicPositionCloudService.update(positionUpdateCloudParam);
    }

    @Override
    public ResponseContent delete(SystemPositionDeleteCloudParam param) {
        ResponseContent rc = new ResponseContent();
        String corpKey = YoukeyiSystemContext.getCorpPrimaryKey();
        if (StringUtils.isBlank(corpKey)) {
            rc.setErrorMessage(ResponseCodeEnum.TOKEN_INVALID.getMessage());
            return rc;
        }
        if (null == param || CollectionUtils.isEmpty(param.getPositionPrimaryKeys())) {
            rc.setErrorMessage(ResponseCodeEnum.PARAMETER_ILLEGAL.getMessage());
            return rc;
        }

        PublicPositionDeleteCloudParam positionDeleteCloudParam = new PublicPositionDeleteCloudParam();
        positionDeleteCloudParam.setPositionPrimaryKeys(param.getPositionPrimaryKeys());
        positionDeleteCloudParam.setUpdateUserKey(YoukeyiSystemContext.getUserPrimaryKey());
        positionDeleteCloudParam.setUpdateUserName(YoukeyiSystemContext.getUserName());
        return publicPositionCloudService.delete(positionDeleteCloudParam);
    }
}
